package dao

import (
	"context"
	"diancan/logUtlis"
	"encoding/json"
	"fmt"
	"github.com/go-redis/redis/v8"
	"time"
)

var RedisMConfig *RedisConfigs

type RedisConfigs struct {
	Ctx context.Context
	RedisClient *redis.Client
}

func NewRedisConfig(hostPort string,password string) *RedisConfigs {
	return &RedisConfigs{
		Ctx:         context.Background(),
		RedisClient: redis.NewClient(&redis.Options{
			Addr:               hostPort,
			Password:           password,
			DB:                 0,
			PoolSize: 128,
			MinIdleConns: 50,
			MaxRetries: 2,
			DialTimeout:  50 * time.Second, // 设置连接超时
			ReadTimeout:  50 * time.Second, // 设置读取超时
			WriteTimeout: 50 * time.Second, // 设置写入超时
		}),
	}
}


func (r *RedisConfigs) NewAddNear(name string,longitude,latitude float64) (err error) {
	aa := &redis.GeoLocation{
		Name:      name,
		Longitude: longitude,
		Latitude:  latitude,
	}
	_, errs := r.RedisClient.GeoAdd(r.Ctx, "Test",aa).Result()
	if errs != nil {
		return errs
	}
	return nil
}

type Test struct {
	Name string `json:"name"`
	Longitude float64 `json:"longitude"`
	Latitude float64 `json:"latitude"`
}


func (r *RedisConfigs) QueryNear(radius float64,count int,sort string) *[]Test {
	locations, err := r.RedisClient.GeoRadius(r.Ctx, "Test", 113.16310570244252, 23.388506426699668, &redis.GeoRadiusQuery{
		Radius: radius,
		Unit:        "km", //这个是显示多少km 或者是 m
		WithGeoHash: true, //这个是hash
		WithCoord:   true, //这个开启后就返回经纬度
		WithDist:    true, //这个开启后就显示距离
		Count:       count,    //这个是查询周围有多杀条数据
		Sort:        sort, //这个是排序的  ASC / desc
	}).Result()
	if err != nil {
		panic(err.Error())
	}

	mTest := make([]Test,0)
	for i := 0; i < len(locations); i++ {
		mmTest := Test{
			Name:      locations[i].Name,
			Longitude: locations[i].Longitude,
			Latitude:  locations[i].Latitude,
		}
		mTest = append(mTest, mmTest)
	}
	return &mTest
}

func (r *RedisConfigs)SetCache(key string,value interface{},duration time.Duration) {
	marshal, err3 := json.Marshal(&value)
	if err3 != nil {
		logUtlis.MainLog.Error("序列化redis写入出错："+err3.Error())
		return
	}
	err2 := r.RedisClient.Set(r.Ctx, key, marshal, duration).Err()
	if err2 != nil {
		logUtlis.MainLog.Error("redis写入数据失败:"+err2.Error())
		return
	}
}

func (r *RedisConfigs) GetCache(key string) ( args []interface{},err error) {
	var testIntfer []interface{}
	result, errs := r.RedisClient.Get(r.Ctx, key).Result()
	if errs != nil {
		return nil, nil
	}
	errr := json.Unmarshal([]byte(result), &testIntfer)
	if errr != nil {
		return nil, nil
	}
	return testIntfer,nil
}

func InitRedis(hostPort string,password string)  {
	RedisMConfig = NewRedisConfig(hostPort, password)
	result, err2 := RedisMConfig.RedisClient.Ping(RedisMConfig.Ctx).Result()

	if err2 != nil {
		fmt.Println("redis连接失败！",err2)
		return
	}
	fmt.Println("redis连接成功！",result)
}


